package 代码题.代理类的操作题目;

import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * java的3种动态代理方式
 */
public class Java3Proxy {

    public static void main(String[] args) {
        jdkProxy();
        cglibProxy();
        javassistProxy();
    }

    //感觉有点多余，这个代码可能有问题, 回调类的实现，将实际对象封装到代理类中。基于接口的操作
    //使用Proxy类
    private static void jdkProxy() {
        final People people = new People();
        IHello proxy = (IHello) Proxy.newProxyInstance(
                Java3Proxy.class.getClassLoader(),
                People.class.getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = method.invoke(people, args);
                        return result;
                    }
                });
        String result = proxy.sayHello("花花");
        System.out.println("执行结果：" + result);
    }

    //同样的将实现类包含到了代理类中，使用Enhancer类
    private static void cglibProxy() {
        People people = new People();

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(people.getClass());
        enhancer.setCallback(
                new MethodInterceptor() {
                    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                        Object result = proxy.invokeSuper(obj, args);
                        return result;
                    }
                });
        People proxy = (People) enhancer.create();
        String result = proxy.sayHello("草草");
        System.out.println("执行结果：" + result);
    }

    //同样的将实现类包含到了代理类中，使用ProxyFactory类
    private static void javassistProxy() {
        ProxyFactory factory=new ProxyFactory();
        factory.setSuperclass(People.class);

        factory.setHandler(new MethodHandler() {
            public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
                Object result=proceed.invoke(self, args);
                return result;
            }
        });

        Class<?> c=factory.createClass();
        People proxy= null;
        try {
            proxy = (People) c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        String result= proxy.sayHello("鱼儿");
        System.out.println("执行结果："+result);
    }

}


interface IHello {
    public String sayHello(String name);
}

class People implements IHello {
    @Override
    public String sayHello(String name) {
        return name + "say hello";
    }
}